#! -coding:utf8 -*-
import threading, sys
import requests
import time
import os


class MulThreadDownload(threading.Thread):
    def __init__(self, url, startpos, endpos, f):
        super(MulThreadDownload, self).__init__()
        self.url = url
        self.startpos = startpos
        self.endpos = endpos
        self.fd = f

    def download(self):
        print("start thread:%s at %s" % (self.getName(), time.time()))
        headers = {"Range": "bytes=%s-%s" % (self.startpos, self.endpos)}
        res = requests.get(self.url, headers=headers)
        # res.text 是将get获取的byte类型数据自动编码，是str类型， res.content是原始的byte类型数据
        # 所以下面是直接write(res.content)
        self.fd.seek(self.startpos)
        self.fd.write(res.content)
        print("stop thread:%s at %s" % (self.getName(), time.time()))
        # f.close()

    def run(self):
        self.download()


class gdown:
    def download(self, url):
        print('start')
        # 获取文件的大小和文件名
        filename = url.split('/')[-1]
        hearders = requests.head(url).headers
        print(hearders)
        filesize = int(hearders['Content-Length'])
        print("%s filesize:%s" % (filename, filesize))

        # 线程数
        threadnum = 5
        # 信号量，同时只允许3个线程运行
        threading.BoundedSemaphore(threadnum)
        # 默认3线程现在，也可以通过传参的方式设置线程数
        step = round(filesize / threadnum)
        mtd_list = []
        start = 0
        end = -1

        # 请空并生成文件
        tempf = open(filename, 'w')
        tempf.close()
        # rb+ ，二进制打开，可任意位置读写
        with open(filename, 'rb+') as f:
            # f.
            fileno = f.fileno()
            # 如果文件大小为11字节，那就是获取文件0-10的位置的数据。如果end = 10，说明数据已经获取完了。
            while end < filesize - 1:
                start = end + 1
                end = start + step - 1
                if end > filesize:
                    end = filesize
                # print("start:%s, end:%s"%(start,end))
                # 复制文件句柄
                dup = os.dup(fileno)
                # print(dup)
                # 打开文件
                fd = os.fdopen(dup, 'rb+', -1)
                # print(fd)
                t = MulThreadDownload(url, start, end, fd)
                t.start()
                mtd_list.append(t)

            for i in mtd_list:
                i.join()
                print("while over")
        print('完成')


if __name__ == "__main__":
    gdown().download("https://download.sublimetext.com/sublime_text_3_build_3211_x64.tar.bz2")
